<template>
  <div>
    <el-table :data="data" border max-height="300">
      <el-table-column width="80" align="center">
        <template #header="{}">
          <el-button icon="el-icon-plus" type="primary" circle @click="addColumn" />
        </template>
        <template #default="scope">
          <el-button icon="el-icon-delete" type="danger" circle @click="deleteColumn(scope.$index)" />
        </template>
      </el-table-column>
      <el-table-column v-for="column in tableColumns" :key="column.prop" :label="column.label" :prop="prop" min-width="100" align="center">
        <template #default="scope">
          <el-select
            v-if="column.prop == 'pageId'"
            v-model="data[scope.$index].pageId"
            placeholder="请选择页面"
            filterable
            clearable
            @change="
              (data) => {
                handlePageAndTypeChange(data, scope.$index, true);
              }
            "
          >
            <el-option v-for="page in settings[scope.$index].pageOptions" :key="page.pageId" :label="page.pageName" :value="page.pageId"> </el-option>
          </el-select>
          <el-select
            v-if="column.prop == 'type'"
            v-model="data[scope.$index].type"
            placeholder="请选择类型"
            filterable
            clearable
            @change="
              (data) => {
                handlePageAndTypeChange(data, scope.$index, true);
              }
            "
          >
            <el-option v-for="(type, idx) in settings[scope.$index].typeOptions" :key="idx" :label="type.label" :value="type.value"> </el-option>
          </el-select>
          <el-cascader
            v-if="column.prop == 'component'"
            :props="CascaderProps"
            :options="settings[scope.$index].compOptions"
            v-model="data[scope.$index].component"
            placeholder="请选择组件"
            filterable
            clearable
            :show-all-levels="false"
            @change="
              (data) => {
                handleCompChange(data, scope.$index, true);
              }
            "
          >
          </el-cascader>
          <el-select v-if="column.prop == 'event'" filterable clearable v-model="data[scope.$index].event" placeholder="请选择方法">
            <el-option v-for="(event, idx) in settings[scope.$index].eventOptions" :key="idx" :label="event.label" :value="event.value"> </el-option>
          </el-select>
          <el-input v-if="column.prop == 'jsonPath'" v-model="data[scope.$index].jsonPath" placeholder="请输入" />
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
import { searchFormByPageId, searchPages } from '../../api/page';
import { useAnvilCodeStore } from '../../store/modules/code';
import formEvents from '../../utils/formEvents';
import fieldMethods from '../exportFieldMethods';
import { Base64 } from 'js-base64'
import { isBase64 } from '@/utils/zmids'

// 该组件专门用来处理所有的关于组件调用的方法配置
export default {
  props: {
    modelValue: {
      type: Array,
      default: () => []
    },
    limit: {
      type: Number,
      default: 0
    },
    fields: {
      type: Array,
      default: () => []
    },
    options: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    return {
      pageOptions: [],
      typeOptions: [
        {
          label: '表单',
          value: 'form'
        },
        {
          label: '组件',
          value: 'component'
        }
      ],
      tableColumns: [
        {
          label: '选择页面',
          prop: 'pageId'
        },
        {
          label: '组件类型',
          prop: 'type'
        },
        {
          label: '选择组件',
          prop: 'component'
        },
        {
          label: '选择事件',
          prop: 'event'
        },
        {
          label: 'JsonPath',
          prop: 'jsonPath'
        }
      ],
      data: [
        // {
        //   pageId: '', // 选择表单
        //   type: '', // 调用的组件类型
        //   component: '', // 调用组件的唯一标识
        //   event: '', // 调用组件的事件名称
        //   jsonPath: '' // 参数根据jsonPath进行处理
        // }
      ],
      settings: [
        // {
        //   pageOptions: [],
        //   typeOptions: [],
        //   compOptions: [],
        //   eventOptions: []
        // }
      ],
      CascaderProps: {
        value: 'uuid',
        label: 'fieldName',
        children: 'children',
        checkStrictly: true,
        emitPath: false
      }
    };
  },
  watch: {
    modelValue: {
      async handler(newVal) {
        if (!this.pageOptions.length) {
          await this.searchPageList();
        }
        this.data = newVal;
        this.initColumns();
      },
      immediate: true
    },
    data: {
      handler(newVal) {
        this.$emit('update:modelValue', newVal);
      },
      deep: true
    }
  },
  async mounted() {},
  methods: {
    async searchPageList() {
      return searchPages().then((res) => {
        // 找到当前页面,放置到列表首条并添加标识
        const { getPageId } = this.useAnvilCodeStore();
        let idx = 0;
        this.pageOptions = res.data.map((item, index) => {
          if (item.pageId == getPageId) {
            idx = index;
            item.pageName = '当前页面' + `(${item.pageName})`;
          }
          return item;
        });
        this.pageOptions.unshift(this.pageOptions.splice(idx, 1)[0]);
      });
    },
    // 获取当前页面内组件列表
    async getPageFields(pageId, isForm = false) {
      return searchFormByPageId(pageId).then((res) => {
        if(!res){
          return []
        }
        let { pageFormJson } = res.data
        if(isBase64(pageFormJson)){
          pageFormJson = Base64.decode(pageFormJson);
        }
        const formOption = JSON.parse(pageFormJson);
        if (isForm) {
          return formOption;
        } else {
          const list = this.getJsonCallableCompList(formOption);
          return list;
        }
      });
    },
    async getCompOptions(pageId, type) {
      const { getPageId } = useAnvilCodeStore();
      if (type == 'form') {
        const options = pageId == getPageId ? this.options : await this.getPageFields(pageId, true);
        return [
          {
            fieldName: '当前表单',
            uuid: pageId,
            options
          }
        ];
      } else {
        const curFields = pageId == getPageId ? this.fields : await this.getPageFields(pageId);
        const curCasaFields = this.getCasaFields(curFields);
        console.log('当前级联', curCasaFields);
        return curCasaFields;
      }
    },
    getEventOptions(type, uuid, fields) {
      if (type == 'form') {
        // 找到pageId对应的表单并在原本方法的基础上添加自定义函数
        const { funcs } = fields[0].options;
        if (funcs && funcs.length) {
          const list = funcs.map((f) => {
            return {
              label: f.funcLabel,
              value: f.funcName
            };
          });
          return [...formEvents, ...list];
        } else {
          return formEvents;
        }
      } else {
        // 寻找树节点
        const findNode = (tree, predicate) => {
          for (const node of tree) {
            if (predicate(node)) {
              return node;
            }
            if (node.children) {
              const found = findNode(node.children, predicate);
              if (found) {
                return found;
              }
            }
          }
          return null;
        };

        const field = findNode(fields, (f) => f.uuid == uuid);

        fields.find((f) => f.uuid == uuid);
        if (field) {
          const methodItem = fieldMethods.find((item) => item.type == field.type);
          const methodsArr = methodItem ? methodItem.methods : [];
          const funcArr = field.funcs ? field.funcs : [];
          const resArr = [
            ...methodsArr,
            ...funcArr.map((f) => {
              return {
                label: f.funcLabel,
                value: f.funcName
              };
            })
          ];
          return resArr;
        }
      }
    },
    addColumn() {
      if (this.limit && this.limit == this.data.length) {
        this.$message.error(`不能超过${this.limit}项！`);
        return;
      }
      const { getPageId } = useAnvilCodeStore();
      this.settings.push({
        pageOptions: this.pageOptions,
        typeOptions: this.typeOptions,
        compOptions: [],
        eventOptions: []
      });
      this.data.push({
        pageId: getPageId, // 选择表单
        type: '', // 调用的组件类型
        component: '', // 调用组件的唯一标识
        event: '', // 调用组件的事件名称
        jsonPath: '' // 参数根据jsonPath进行处理
      });
    },
    deleteColumn(index) {
      this.settings.splice(index, 1);
      this.data.splice(index, 1);
    },
    async handlePageAndTypeChange(value, index, isClear) {
      const { pageId, type } = this.data[index];

      if (pageId && type) {
        this.settings[index].compOptions = await this.getCompOptions(pageId, type);
        // 是否重置component和event字段
        if (isClear) {
          this.data[index].component = '';
          this.data[index].event = '';
        }
      }
    },
    handleCompChange(value, index, isClearEvent) {
      const { type } = this.data[index];
      const { compOptions } = this.settings[index];
      this.settings[index].eventOptions = this.getEventOptions(type, value, compOptions);
      // 是否重置event字段
      if (isClearEvent) {
        this.data[index].event = '';
      }
    },
    async initColumns() {
      if (this.data && this.data.length) {
        this.data.map(async (item, index) => {
          const { pageId, type, component } = item;
          this.settings.push({
            pageOptions: this.pageOptions,
            typeOptions: this.typeOptions,
            compOptions: [],
            eventOptions: []
          });
          await this.handlePageAndTypeChange(undefined, index);
          this.handleCompChange(component, index);
        });
      }
    },
    // 获取级联组件列表
    getCasaFields(fields) {
      return fields
        .map((f) => {
          const { type, fieldName } = f;
          // 处理聚合类型的组件
          if (type == 'customButtonGroup') {
            const children = f.btnGroup.map((btn) => {
              return {
                ...btn,
                fieldName: btn.buttonName
              };
            });
            return {
              ...f,
              children
            };
          } else {
            return {
              ...f,
              fieldName: f.fieldName ? f.fieldName : f.label ? f.label : '未命名组件',
              children: f.children && f.children.column ? f.children.column : [],
              disabled: false
            };
          }
        })
        .filter((f) => f.uuid);
    }
  }
};
</script>
